package com.wlyuan.open.scanner.application.async;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author lijing
 * @description
 */
@EnableAsync
@Configuration
public class ThreadPoolConfig {


    @Bean("asyncExecutor")
    public Executor getAsyncExecutor() {
        //0.9是指远程调用所占的时间，在整个过程中所占的时间比例 每个线程CPU运行时间为0.1s，而线程等待时间（非CPU运行时间，比如IO）为0.9
        double blockingCoefficient = 0.9;
        //cpu核数
        int numberOfCores = Runtime.getRuntime().availableProcessors();
        //io密集型线程池大小
        int poolSize = (int) (numberOfCores / (1 - blockingCoefficient));

        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        //线程名称前缀
        threadPool.setThreadNamePrefix("scanner-sync-");
        //核心线程数，默认为1
        threadPool.setCorePoolSize(poolSize);
        //最大线程数，默认为Integer.MAX_VALUE
        threadPool.setMaxPoolSize(poolSize);
        //队列最大长度，默认为Integer.MAX_VALUE
        threadPool.setQueueCapacity(20000);
        //线程池维护线程所允许的空闲时间，默认为60s
        threadPool.setKeepAliveSeconds(300);
        //容器停止时是否等待job执行完，默认为false
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        //容器停止时等待job执行的秒数，默认为0
        threadPool.setAwaitTerminationSeconds(3 * 60);
        //主线程直接执行该任务，执行完之后尝试添加下一个任务到线程池中，可以有效降低向线程池内添加任务的速度
        threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        threadPool.initialize();
        return threadPool;
    }

}
